/**
 * @brief   RUDP协议服务器端实现模块。服务器实际是一个RUDP的端点，在这个端点内有一个
 *         对点link信息记录表。当服务器接收到数据后
 * @version 1.0
 * @date    2018-3-2
 * @author  宋炜
*/

#ifndef __RDUP_SERVER_HPP__
#define __RDUP_SERVER_HPP__
#include <string>
#include <atomic>
#include <map>
#include "base.hpp"
#include "misc.h"
#include "link.hpp"
class rudpServer : public rudp
{
public:
	struct stclient_tbl{
		int 	                          count;          // 连接的客户端的数量
		std::map< hash_t , rudpLink *>    m_cli;          // 连接的客户端
		rudp_buf_t                        m_buf;          // 多包数据缓冲

	        typedef std::map< hash_t , rudpLink * >::iterator  linkIt_t;

		stclient_tbl(){ count = 0;}
		~stclient_tbl();
		linkIt_t find( const struct sockaddr * add );
		bool has( const struct sockaddr * add );
		/**
		 * @brief 增加连接
		*/
   	        void insert( rudpLink * clink , const struct sockaddr * add ); 
		/**
		 * @brief 删除客户端
		 * @param add
		 * @param hash_t 
		*/
		void erase( const struct sockaddr * add );
		void erase( hash_t t );

		bool is_ok( linkIt_t it )
		{
		     return it == m_cli.end(); 
		}
	};
private:
        stclient_tbl    m_tbl;                               // 客户端列表
private:
	/**
	 * @brief 根据数据来源将书记派发给不同link
	 * @param pkge , 数据
	 * @param add , 数据来源
	*/
	void dispatch( rudp_pkge_t * pkge , const struct sockaddr * add );
        void do_on_send( rudp_pkge_t * pkge , const struct sockaddr * add );
	void do_on_connect( rudp_pkge_t * pkge , const struct sockaddr * add );
	void do_on_connect_echo( rudp_pkge_t * pkge , const struct sockaddr * add );
	void do_on_connect_echo_echo( rudp_pkge_t * pkge , const struct sockaddr * add );
	void do_on_close( rudp_pkge_t * pkge , const struct sockaddr * add );
	void do_on_close_echo( rudp_pkge_t * pkge , const struct sockaddr * add );
	/**
	 * @brief 接收连接。这个函数对于客户端来说不做任何事情。在服务器端对象中
	 *        要对这个函数进行重载实现接受连接处理操作
	 * @param 对点地址
	*/
	virtual void on_accept( const struct sockaddr * add );
	virtual void on_close( const struct sockaddr * add ){}
	virtual void on_close_echo( const struct sockaddr * add ){}
public:
	/**
	 * @brief 构造对象
	 * @param port ，监听端口
	 */
        rudpServer( int port );
	virtual ~rudpServer();
	/**
	 * @brief 向对端发送关闭连接请求
	 */
	void close( hash_t t );
	void close( const struct sockaddr * add );
	/**
	 * @brief 关闭所有的客户端
	*/
	void close_all();
};

#endif
